﻿using System;
using innovations.util.exts.mathdotnet;
using MathNet.Numerics.LinearAlgebra.Double;

namespace innovations.ml.core.solvers
{
    public class CG : Solver
    {
        public CG() : base() { }

        public override void Run(int numberOfLabels = 1)
        {
            if (numberOfLabels == 0)
                throw new ArgumentException("Number of labels should be greater than zero.");
            Model.Solver = this;

            for (int i = 0; i < numberOfLabels; i++)
            {
                Model.SetLogicalY(i);
                double epsg = 0.0000000001;
                double epsf = 0;
                double epsx = 0;
                int maxits = Iterations;
                alglib.mincgstate state;
                alglib.mincgreport rep;
                double[] tempTheta = Model.Theta.ToArray();
                alglib.mincgcreate(tempTheta, out state);
                alglib.mincgsetprecscale(state);
                alglib.mincgsetcond(state, epsg, epsf, epsx, maxits);
                alglib.mincgoptimize(state, Model.ComputeCostAndGradient, null, null);
                alglib.mincgresults(state, out tempTheta, out rep);
                Model.J = state.f;
                if (i == 0)
                    Model.MultiClassTheta = new DenseMatrix(numberOfLabels, this.Model.X.ColumnCount);
                Model.MultiClassTheta.SetRow(i, tempTheta);
                Model.Theta = new DenseVector(Model.X.ColumnCount);
            }
        }
        /*
*/
    }
}
